package com.ruoyi.school.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.enums.FileTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileTypeUtils;
import com.ruoyi.school.domain.*;
import com.ruoyi.school.domain.vo.*;
import com.ruoyi.school.enums.AuditStatusEnum;
import com.ruoyi.school.enums.AuditTypeEnum;
import com.ruoyi.school.enums.WallStateEnum;
import com.ruoyi.school.handler.wall.WallTopThree;
import com.ruoyi.school.mapper.PacActualOutputParticipationMapper;
import com.ruoyi.school.service.*;
import com.ruoyi.school.mapper.PacActualOutputMapper;
import com.ruoyi.school.utils.CommonUtils;
import com.ruoyi.system.domain.TableData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.PageUtils.startPage;
import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * @author jeremylin
 * @description 针对表【pac_actual_output(实战成果表)】的数据库操作Service实现
 * @createDate 2025-05-27 03:22:10
 */
@Service
public class PacActualOutputServiceImpl extends ServiceImpl<PacActualOutputMapper, PacActualOutput>
        implements PacActualOutputService {
    @Resource
    private StudentService studentService;

    @Resource
    private PacAuditRecordsService pacAuditRecordsService;

    @Resource
    private PacTeacherService pacTeacherService;

    @Resource
    private PacAcademicOutputParticipationService pacAcademicOutputParticipationService;

    @Resource
    private PacActualOutputParticipationService pacActualOutputParticipationService;

    @Resource
    private PacClassTeacherService pacClassTeacherService;

    @Override
    public TableData<PacActualOutputVo> getList(PacAcademicOutputVo academicOutput) {
        // 查询学生信息
        Student studentParams = new Student();
        studentParams.setStuPhone(academicOutput.getStuPhone());
        studentParams.setStuFaculties(academicOutput.getStuFaculties());
        studentParams.setYearEnrollment(academicOutput.getYearEnrollment());
        studentParams.setStuClass(academicOutput.getStuClass());

        if(academicOutput.getTeacherType() != null){
            List<PacClassInfoVo> pacClassInfoVos;
            if(academicOutput.getTeacherType() == 0){
                // 获取当前老师绑定的班级id
                pacClassInfoVos = pacClassTeacherService.selectByTeacherByKey(getLoginUser().getUser(),"teacher");
            }else if(academicOutput.getTeacherType() == 1){
                pacClassInfoVos = pacClassTeacherService.selectByTeacherByKey(getLoginUser().getUser(),"teacher2");
            }else{
                pacClassInfoVos = pacClassTeacherService.selectByTeacherByKey(getLoginUser().getUser(),"duizhang");
            }
            if(pacClassInfoVos != null && !pacClassInfoVos.isEmpty()){
                List<Integer> classIds = pacClassInfoVos.stream().map(PacClass::getId).collect(Collectors.toList());
                // 设置当前老师可以查询的班级
                studentParams.setClassIds(classIds);
            }
        }

        if(academicOutput.getStuIds() == null){
            return TableData.<PacActualOutputVo>builder()
                    .total(0L)
                    .build();
        }


        List<Student> studentSearch = studentService.selectInfo(studentParams);
        if (!studentSearch.isEmpty()) {
            List<Integer> ids = studentSearch.stream().map(Student::getId).collect(Collectors.toList());
            academicOutput.setStuIds(ids);
        }
        startPage();
//        List<PacActualOutput> list = lambdaQuery()
//                .likeRight(StringUtils.isNotEmpty(academicOutput.getStuName()), PacActualOutput::getStuName, academicOutput.getStuName())
//                .eq(StringUtils.isNotEmpty(academicOutput.getStuNum()), PacActualOutput::getStuNum, academicOutput.getStuNum())
//                .eq(Objects.nonNull(academicOutput.getAcAudit()), PacActualOutput::getAcAudit, academicOutput.getAcAudit())
//                .eq(Objects.nonNull(academicOutput.getAcWall()), PacActualOutput::getAcWall, academicOutput.getAcWall())
//                .eq(Objects.nonNull(academicOutput.getStuId()), PacActualOutput::getStuId, academicOutput.getStuId())
//                .eq(Objects.nonNull(academicOutput.getAcDanwei()), PacActualOutput::getAcDanwei, academicOutput.getAcDanwei())
//                .likeRight(Objects.nonNull(academicOutput.getAcTitle()), PacActualOutput::getAcTitle, academicOutput.getAcTitle())
//                .in(Objects.nonNull(academicOutput.getStuIds()), PacActualOutput::getStuId, academicOutput.getStuIds())
//                .list();
        List<PacActualOutput> list = baseMapper.getList(academicOutput);
        // 找到学生id
        List<Long> stuIds = list.stream().map(PacActualOutput::getStuId).collect(Collectors.toList());
        List<Student> students = studentService.selectByStuIds(stuIds);
        Map<Integer, Student> studentMap = students.stream().collect(Collectors.toMap(Student::getId, student -> student));
        ArrayList<PacActualOutputVo> academicOutputVos = new ArrayList<>();
        list.forEach(item -> {
            PacActualOutputVo vo = new PacActualOutputVo();
            vo.setId(item.getId());
            vo.setAcTitle(item.getAcTitle());
            vo.setAcFile(item.getAcFile());
            vo.setAcAudit(item.getAcAudit());
            vo.setAcWall(item.getAcWall());
            vo.setStuId(item.getStuId());
            vo.setStuName(item.getStuName());
            vo.setStuNum(item.getStuNum());
            Student student = studentMap.get(item.getStuId().intValue());

            vo.setStuClass(student.getStuClass());
            vo.setStuFaculties(student.getStuFaculties());
            vo.setYearEnrollment(student.getYearEnrollment());
            vo.setCreateTime(item.getCreateTime());

            String instructorTeacherId = item.getInstructorTeacherId();
            List<PacTeacher> teachers = pacTeacherService.listByIds(Arrays.asList(instructorTeacherId.split(",")));
            vo.setTeachers(teachers);

            PacTeacher academicTeacherInfo = pacTeacherService.getAcademicTeacherInfo(student.getClassId());
            if(academicTeacherInfo != null){
                vo.setAcademicTeacher(academicTeacherInfo.getTeacherName());
            }

            vo.setPracticeUnit(item.getAcDanwei());

            // 把团队成员查出来
            List<ActualOutputParticipationListVo> participants = pacActualOutputParticipationService.getParticipants(item.getId());
            vo.setParticipants(participants);

            academicOutputVos.add(vo);
        });

        PageInfo pageInfo = new PageInfo(list);

        TableData<PacActualOutputVo> tableData = TableData.<PacActualOutputVo>builder()
                .data(academicOutputVos)
                .total(pageInfo.getTotal())
                .build();


        return tableData;
    }

    @Override
    public PacActualOutput getDetails(PacActualOutput pacAcademicOutput) {
        if (pacAcademicOutput.getId() == null) {
            throw new BaseException("id不能为空");
        }
        PacActualOutput one = lambdaQuery().eq(PacActualOutput::getId, pacAcademicOutput.getId()).one();
        // 把字符串转集合
        String instructorTeacherId = one.getInstructorTeacherId();
        List<String> list = Arrays.asList(instructorTeacherId.split(","));
        List<Long> collect = list.stream().map(id -> Long.valueOf(id)).collect(Collectors.toList());
        one.setTeacherIds(collect);
        one.setMemberIds(pacActualOutputParticipationService.selectMemberIds(pacAcademicOutput.getId()));
        return one;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(PacActualOutput pacAcademicOutput) {
        validateAdd(pacAcademicOutput);
        // 插入学生信息
        Long stuId = pacAcademicOutput.getStuId();
        Student student = studentService.getById(stuId);
        pacAcademicOutput.setStuName(student.getStuName());
        pacAcademicOutput.setStuNum(student.getStuNum());
        pacAcademicOutput.setStuArea(student.getSmallTeam());
        List<Long> teacherIds = pacAcademicOutput.getTeacherIds();
        // 逗号分隔
        String teacherIdsStr = StringUtils.join(teacherIds, ",");
        pacAcademicOutput.setInstructorTeacherId(teacherIdsStr);

        PacTeacher pacTeacher = pacTeacherService.getAcademicTeacherInfo(student.getClassId());
        if (pacTeacher != null) {
            pacAcademicOutput.setAcademicTeacherId(pacTeacher.getId().longValue());
        }
        if (Objects.nonNull(pacAcademicOutput.getAcFile())) {
            FileTypeEnum fileTypeName = FileTypeUtils.getFileTypeName(pacAcademicOutput.getAcFile());
            pacAcademicOutput.setAcFileType(fileTypeName.getCode());
        }

        if (save(pacAcademicOutput)) {
            PacAuditRecords pacAuditRecords = getPacAuditRecords(pacAcademicOutput, student);

            if (pacAuditRecordsService.add(pacAuditRecords)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 参与实战成果
     *
     * @param pacAcademicOutput
     * @return
     */
    @Override
    public boolean join(PacActualOutput pacAcademicOutput) {
        return false;
    }

    @Override
    public long countByAudit() {
        // 审核通过数量
        long count = lambdaQuery().eq(PacActualOutput::getAcAudit, 2).count();
        // 查询通过实战 对应的参与人数量
        long count1 = pacActualOutputParticipationService.countByAudit();
        return count1 + count;
    }

    /**
     * 前五数据
     *
     * @param id
     * @return
     */
    @Override
    public List<PacActualOutput> selectStuTop5(Integer id) {
        List<PacActualOutput> list = lambdaQuery()
                .eq(PacActualOutput::getAcFileType, FileTypeEnum.IMAGE.getCode())
                .eq(PacActualOutput::getAcAudit, AuditStatusEnum.AUDITED.getCode())
                .eq(PacActualOutput::getStuId, id)
                .orderByDesc(PacActualOutput::getCreateTime)
                .last("LIMIT 5")
                .list();

        return list;
    }

    /**
     * 新增校验
     *
     * @param pacAcademicOutput
     */
    private void validateAdd(PacActualOutput pacAcademicOutput) {
        if (pacAcademicOutput.getAcTime() == null) {
            throw new BaseException("成果时间不能为空");
        }
    }

    @Override
    @Transactional
    public boolean addByStu(PacActualOutput pacAcademicOutput) {
        // 插入学生信息
        validateAdd(pacAcademicOutput);
        // 插入学生信息
        Student student = CommonUtils.getStudent();
        insertRecord(pacAcademicOutput, student);
        if (pacAcademicOutput.getMemberIds() != null) {
            List<Student> students = studentService.selectByStuIds(pacAcademicOutput.getMemberIds());
            students.forEach(item -> {
                PacActualOutputParticipation pacAcademicOutputParticipation = new PacActualOutputParticipation();
                pacAcademicOutputParticipation.setOutputId(pacAcademicOutput.getId());
                pacAcademicOutputParticipation.setParticipantId(item.getId().longValue());
                pacActualOutputParticipationService.join(pacAcademicOutputParticipation);
            });
        }
        return true;
    }

    private boolean insertRecord(PacActualOutput pacAcademicOutput, Student student) {
        pacAcademicOutput.setStuName(student.getStuName());
        pacAcademicOutput.setStuNum(student.getStuNum());
        pacAcademicOutput.setStuArea(student.getSmallTeam());
        pacAcademicOutput.setStuId(student.getId().longValue());
        List<Long> teacherIds = pacAcademicOutput.getTeacherIds();
        // 逗号分隔
        String teacherIdsStr = StringUtils.join(teacherIds, ",");
        pacAcademicOutput.setInstructorTeacherId(teacherIdsStr);

        PacTeacher pacTeacher = pacTeacherService.getAcademicTeacherInfo(student.getClassId());
        if (pacTeacher != null) {
            pacAcademicOutput.setAcademicTeacherId(pacTeacher.getId().longValue());
        }
        if (Objects.nonNull(pacAcademicOutput.getAcFile())) {
            FileTypeEnum fileTypeName = FileTypeUtils.getFileTypeName(pacAcademicOutput.getAcFile());
            pacAcademicOutput.setAcFileType(fileTypeName.getCode());
        }

        if (save(pacAcademicOutput)) {
            PacAuditRecords pacAuditRecords = getPacAuditRecords(pacAcademicOutput, student);

            if (pacAuditRecordsService.add(pacAuditRecords)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean edit(PacActualOutput pacAcademicOutput) {
        Long id = pacAcademicOutput.getId();

        PacActualOutput byId = getById(id);
        if (byId == null) {
            throw new BaseException("记录异常");
        }

        // 判断状态，如果已通过不让他更新
        if (byId.getAcAudit().equals(AuditStatusEnum.AUDITED.getCode())) {
            throw new BaseException("已通过，请勿修改");
        }

        Long stuId = pacAcademicOutput.getStuId();
        Student student = studentService.getById(stuId);
        pacAcademicOutput.setStuName(student.getStuName());
        pacAcademicOutput.setStuNum(student.getStuNum());
        pacAcademicOutput.setStuArea(student.getSmallTeam());
        List<Long> teacherIds = pacAcademicOutput.getTeacherIds();
        // 逗号分隔
        String teacherIdsStr = StringUtils.join(teacherIds, ",");
        pacAcademicOutput.setInstructorTeacherId(teacherIdsStr);

        PacTeacher pacTeacher = pacTeacherService.getAcademicTeacherInfo(student.getClassId());
        if (pacTeacher != null) {
            pacAcademicOutput.setAcademicTeacherId(pacTeacher.getId().longValue());
        }
        if (Objects.nonNull(pacAcademicOutput.getAcFile())) {
            FileTypeEnum fileTypeName = FileTypeUtils.getFileTypeName(pacAcademicOutput.getAcFile());
            pacAcademicOutput.setAcFileType(fileTypeName.getCode());
        }

        pacAcademicOutput.setAcAudit(AuditStatusEnum.UNAUDITED.getCode());

        if (updateById(pacAcademicOutput)) {
            PacAuditRecords pacAuditRecords = getPacAuditRecords(pacAcademicOutput, student);
            pacAuditRecordsService.updateByRecord(pacAuditRecords);

            // 先删除团队成员
            pacActualOutputParticipationService.deleteByOutPutId(pacAcademicOutput.getId());
            // 重新添加
            if (pacAcademicOutput.getMemberIds() != null) {
                List<Student> students = studentService.selectByStuIds(pacAcademicOutput.getMemberIds());
                students.forEach(item -> {
                    PacActualOutputParticipation pacAcademicOutputParticipation = new PacActualOutputParticipation();
                    pacAcademicOutputParticipation.setOutputId(pacAcademicOutput.getId());
                    pacAcademicOutputParticipation.setParticipantId(item.getId().longValue());
                    pacActualOutputParticipationService.join(pacAcademicOutputParticipation);
                });
            }
            return true;
        }


        return false;
    }

    @Override
    public boolean editByStu(PacActualOutput pacAcademicOutput) {
        Long id = pacAcademicOutput.getId();

        PacActualOutput byId = getById(id);
        if (byId == null) {
            throw new BaseException("记录异常");
        }

        // 判断状态，如果已通过不让他更新
        if (byId.getAcAudit().equals(AuditStatusEnum.AUDITED.getCode())) {
            throw new BaseException("已通过，请勿修改");
        }
        Student loginStu = CommonUtils.getStudent();

        Student student = studentService.getById(loginStu.getId());
        pacAcademicOutput.setStuName(student.getStuName());
        pacAcademicOutput.setStuNum(student.getStuNum());
        pacAcademicOutput.setStuId(student.getId().longValue());

        if (Objects.nonNull(pacAcademicOutput.getAcFile())) {
            FileTypeEnum fileTypeName = FileTypeUtils.getFileTypeName(pacAcademicOutput.getAcFile());
            pacAcademicOutput.setAcFileType(fileTypeName.getCode());
        }

        if (updateById(pacAcademicOutput)) {
            PacAuditRecords pacAuditRecords = getPacAuditRecords(pacAcademicOutput, student);
            pacAuditRecordsService.updateByRecord(pacAuditRecords);
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(PacActualOutput pacAcademicOutput) {
        if (removeById(pacAcademicOutput)) {
            // 同时删除审批记录
            pacAuditRecordsService.deleteByOutPutId(pacAcademicOutput.getId(),AuditTypeEnum.PAC_WALL_TYPE_PRACTICE.getCode());
            return true;
        }
        return false;
    }

    @Override
    public boolean wall(AcademicCommonVo academicCommonVo) {
        List<Long> ids = academicCommonVo.getIds();
        if (ids != null && !ids.isEmpty()) {
            List<PacActualOutput> list = new ArrayList<>();
            ids.forEach(item -> {
                PacActualOutput pacAcademicOutput = new PacActualOutput();
                pacAcademicOutput.setId(item);
                pacAcademicOutput.setAcWall(2);
                list.add(pacAcademicOutput);
            });
            if (updateBatchById(list)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<PacActualOutput> myList(PacActualOutput pacAcademicOutput) {
        Student student = CommonUtils.getStudent();
        if (student != null) {
            List<PacActualOutput> list = lambdaQuery()
                    .likeRight(StringUtils.isNotEmpty(pacAcademicOutput.getAcTitle()),
                            PacActualOutput::getAcTitle, pacAcademicOutput.getAcTitle())
                    .eq(Objects.nonNull(pacAcademicOutput.getAcAudit()), PacActualOutput::getAcAudit, pacAcademicOutput.getAcAudit())
                    .eq(Objects.nonNull(pacAcademicOutput.getAcFileType()), PacActualOutput::getAcFileType, pacAcademicOutput.getAcFileType())
                    .eq(PacActualOutput::getStuId, student.getId())
                    .eq(Objects.nonNull(pacAcademicOutput.getAcDanwei()), PacActualOutput::getAcDanwei, pacAcademicOutput.getAcDanwei())
                    .between(Objects.nonNull(pacAcademicOutput.getStartTime()), PacActualOutput::getCreateTime, pacAcademicOutput.getStartTime(), pacAcademicOutput.getEndTime())
                    .apply(Objects.nonNull(pacAcademicOutput.getTeacherId()), "FIND_IN_SET({0}, instructor_teacher_id) > 0", pacAcademicOutput.getTeacherId())
                    .list();

            list.forEach(item -> {
                String instructorTeacherId = item.getInstructorTeacherId();
                List<PacTeacher> teachers = pacTeacherService.listByIds(Arrays.asList(instructorTeacherId.split(",")));
                item.setTeachers(teachers);
                List<ActualOutputParticipationListVo> participants = pacActualOutputParticipationService.getParticipants(item.getId());
                item.setParticipants(participants);
            });
            return list;
        }
        return Collections.emptyList();
    }

    /**
     * 审批
     *
     * @param pacAcademicOutput
     */
    @Override
    public void audit(PacActualOutput pacAcademicOutput) {
        updateById(pacAcademicOutput);
        // 将参与人员 弄成参与状态
        pacAcademicOutputParticipationService.updateParticipantState(pacAcademicOutput.getId());
    }

    /**
     * 下墙
     *
     * @param academicCommonVo
     * @return
     */
    @Override
    public boolean unWall(AcademicCommonVo academicCommonVo) {
        List<Long> ids = academicCommonVo.getIds();
        if (ids != null && !ids.isEmpty()) {
            List<PacActualOutput> list = new ArrayList<>();
            ids.forEach(item -> {
                PacActualOutput pacAcademicOutput = new PacActualOutput();
                pacAcademicOutput.setId(item);
                pacAcademicOutput.setAcWall(1);
                list.add(pacAcademicOutput);
            });
            if (updateBatchById(list)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 荣誉墙前三
     *
     * @param builder
     * @return
     */
    @Override
    public List<HonorWallTopThreeVo> getTopThree(WallTopThree builder) {
        List<PacActualOutput> list = lambdaQuery()
                .eq(PacActualOutput::getAcWall, WallStateEnum.WALL_STATE_YES.getCode())
                .eq(Objects.nonNull(builder.getFileType()), PacActualOutput::getAcFileType, builder.getFileType())
                .eq(Objects.nonNull(builder.getStuId()), PacActualOutput::getStuId, builder.getStuId())
                .between(Objects.nonNull(builder.getStartTime()), PacActualOutput::getCreateTime, builder.getStartTime(), builder.getEndTime())
                .orderByDesc(PacActualOutput::getCreateTime)
                .last("LIMIT 3")
                .list();

        if (list != null && !list.isEmpty()) {
            return list.stream().map(item -> {
                HonorWallTopThreeVo honorWallTopThreeVo = new HonorWallTopThreeVo();
                honorWallTopThreeVo.setAcTitle(item.getAcTitle());
                honorWallTopThreeVo.setAcFile(item.getAcFile());
                honorWallTopThreeVo.setAcFileType(item.getAcFileType());
                honorWallTopThreeVo.setStuName(item.getStuName());
                return honorWallTopThreeVo;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 获取学生的荣誉列表
     *
     * @param wallTopThree
     * @return
     */
    @Override
    public List<HonorWallTopThreeVo> getStuHonorList(WallTopThree wallTopThree) {
        List<PacActualOutput> list = lambdaQuery()
                .eq(Objects.nonNull(wallTopThree.getFileType()), PacActualOutput::getAcFileType, wallTopThree.getFileType())
                .eq(Objects.nonNull(wallTopThree.getStuId()), PacActualOutput::getStuId, wallTopThree.getStuId())
                .orderByDesc(PacActualOutput::getCreateTime)
                .list();

        if (list != null && !list.isEmpty()) {
            return list.stream().map(item -> {
                HonorWallTopThreeVo honorWallTopThreeVo = new HonorWallTopThreeVo();
                honorWallTopThreeVo.setAcTitle(item.getAcTitle());
                honorWallTopThreeVo.setAcFile(item.getAcFile());
                honorWallTopThreeVo.setAcFileType(item.getAcFileType());
                honorWallTopThreeVo.setStuName(item.getStuName());
                return honorWallTopThreeVo;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }


    private static PacAuditRecords getPacAuditRecords(PacActualOutput pacAcademicOutput, Student student) {
        PacAuditRecords pacAuditRecords = new PacAuditRecords();
        pacAuditRecords.setAuditType(AuditTypeEnum.PAC_WALL_TYPE_PRACTICE.getCode());
        pacAuditRecords.setAuditStu(pacAcademicOutput.getStuName());
        pacAuditRecords.setAuditStuClass(student.getStuClass());
        pacAuditRecords.setAuditFile(pacAcademicOutput.getAcFile());
        pacAuditRecords.setAuditTitle(pacAcademicOutput.getAcTitle());
        pacAuditRecords.setAuditStuId(pacAcademicOutput.getStuId());
        pacAuditRecords.setAuditRecordId(pacAcademicOutput.getId());
        pacAuditRecords.setAuditFileType(pacAcademicOutput.getAcFileType());
        return pacAuditRecords;
    }
}




